"""
    通过Python编程完成一个银行ATM机模拟系统，具备如下功能:

    (1)登陆验证：用户输入用户名密码登陆，检测用户名是否存在以及用户名密码是否匹配；用户名密码共有三次输入机会，超过三次系统退出。

    (2)菜单界面：登陆成功后显示功能操作界面，输入序号选择对应功能。

    (3)用户注册：用户可以输入用户名和密码创建自己的账号，并输入电话号码等信息，如果用户名存在则让用户重新输入用户名。注册后免费赠送5000元余额。

    (4)账户管理：用户可以随时查看自己的账户余额。用户可以输入其他账户用户名，实现转账功能；转账时用户名必须存在，否则提示异常。用户也可以模拟实现存取款功能。

    (5)用户名和密码以及账户信息等必须永久保存。且基于命令行完成，不需要开发GUI界面。

"""


def check_loggin(fn, loggin_num=0):
    def inter():
        nonlocal loggin_num
        while loggin_num < 3:
            name = input('请输入用户名:')
            password = input('请输入密码:')
            user, loggin_status = fn(name, password)
            if loggin_status:
                return user, loggin_status
            else:
                loggin_num += 1
                print('用户名或密码错误')
        print('你输入的错误超过三次，系统已退出。')
        quit()

    return inter


@check_loggin
def loggin(user: str, password: str):
    return (user, True if user in user_password_dict.keys() and password == user_password_dict.get(user)[0] else False)


def menu(user):
    while True:
        print('=' * 10, '欢迎登陆ATM系统', '=' * 10)
        button = ['余额查询', '实时取账', '实时存款', '实时转账', '系统退出']
        for num, func in enumerate(button, 1):
            print('{:>10},  {}'.format(num, func))
        print('=' * 10, '欢迎登陆ATM系统', '=' * 10)
        user_input = input('请输入功能序号>>>')

        if user_input == '1':
            print('用户{}的账户余额为{}'.format(user, user_password_dict.get(user)[2]))
        elif user_input == '3' or user_input == '2' or user_input == '4':
            move_money(user, user_input)
        elif user_input == '5':
            quit()
        else:
            print('输入错误')


def wrapper(fn):
    def inter(src, funcnum):
        if funcnum == '2':
            status = False
        elif funcnum == '3':
            status = True
        elif funcnum == '4':
            rcpt = input('请输入收款人:')
            if rcpt not in user_password_dict.keys():
                print('你输入的收款人不存在,系统已退出')
                quit()
            status = None
        res = fn(src, status, rcpt=None)
        return res

    return inter


@wrapper
def move_money(src: str, status=None, rcpt: str = None):
    money = int(input('请输入金额:'))
    if rcpt:
        user_password_dict.get(src)[2] = str(int(user_password_dict.get(src)[2]) - money)
        user_password_dict.get(rcpt)[2] = str(int(user_password_dict.get(rcpt)[2]) + money)

    user_password_dict.get(src)[2] = str(int(user_password_dict.get(src)[2]) + money) if status \
        else str(int(user_password_dict.get(src)[2]) - money)

    _change_move()


def regist():
    print('请依次输入姓名，密码，手机号')
    name = input('请输入名字:')
    if name in user_password_dict.keys():
        print('你输入的名字已存在')
        regist()
    else:
        password = input('请输入密码:')
        telephone_number = input('请输入电话号码:')
        money = 5000
        user_password_dict[name] = [password, telephone_number, money]
        _change_move()


def _change_move():
    tmpdict = user_password_dict
    with open('user_information.txt', 'w+', encoding='utf-8') as f:
        for k, v in tmpdict.items():
            f.write('{}:{}:{}:{}\n'.format(k, v[0], v[1], v[2]))


if __name__ == '__main__':

    while True:
        with open('user_information.txt', 'r', encoding='utf-8') as f:
            user_password_dict = {
                line.split(':')[0]: [line.split(':')[1], line.split(':')[2], line.split(':')[3].strip()]
                for line in f.readlines()}

        print('=' * 10, '欢迎登陆ATM系统', '=' * 10)

        button = ['用户登陆', '用户注册', '退出']
        for k, func in enumerate(button, 1):
            print('{:>10},  {}'.format(k, func))

        print('=' * 10, '欢迎登陆ATM系统', '=' * 10)


        user_input = input('请输入需要执行的功能的序号>>')

        if user_input == '1':
            menu(loggin()[0])
        elif user_input == '2':
            regist()
        elif user_input == '3':
            exit()
        else:
            print('输入有误')
# 完成的不错，把登录功能封装为装饰器，这个不错